﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Text.RegularExpressions;
using AgiliTrain.PhoneyTools;

namespace GooNews.ViewModels
{
  /// <summary>
  /// 
  /// </summary>
  public class FeedInfo : ObservableObject
  {

    /// <summary>
    /// 
    /// </summary>
    public enum FeedType
    {
      /// <summary>
      /// 
      /// </summary>
      None = 0,
      /// <summary>
      /// 
      /// </summary>
      BuiltIn,
      /// <summary>
      /// 
      /// </summary>
      Search
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="FeedInfo"/> class.
    /// </summary>
    public FeedInfo()
    {
      Enabled = true;
    }

    string _title;

    /// <summary>
    /// Gets or sets the title.
    /// </summary>
    /// <value>
    /// The title.
    /// </value>
    public string Title
    {
      get { return _title; }
      set
      {
        _title = value;
        RaisePropertyChanged("Title");
      }
    }

    /// <summary>
    /// Gets or sets the URL.
    /// </summary>
    /// <value>
    /// The URL.
    /// </value>
    public string Url
    {
      get 
      {
        if (Type == FeedType.BuiltIn)
        {
          return string.Format("http://news.google.com/news?ned={0}&topic={1}&output=rss", App.ViewModel.Options.CurrentNedKey, Topic);
        }
        else
        {
          return string.Format("http://news.google.com/news?ned={0}&q={1}&output=rss", App.ViewModel.Options.CurrentNedKey, Topic);
        }
      }
      set
      {
        SniffInfo(value);
      }
    }

    /// <summary>
    /// Sniffs the info.
    /// </summary>
    /// <param name="value">The value.</param>
    private void SniffInfo(string value)
    {
      if (this.Type != FeedType.None ||
        string.IsNullOrEmpty(Topic))
      {
        // Get Query Strings
        var ex = new Regex(@"[\?&](?<name>[^&=]+)=(?<value>[^&=]+)");
        var matches = ex.Matches(value);
        var dict = new Dictionary<string, string>();
        foreach (Match m in matches)
        {
          dict[m.Groups["name"].Value] = m.Groups["value"].Value;
        }


        Type = dict.ContainsKey("q") ? FeedType.Search : FeedType.BuiltIn;


        if (Type == FeedType.BuiltIn)
        {
          Topic = dict["topic"];
        }
        else
        {
          Topic = dict["q"];
        }
      }
    }

    FeedType _type;

    /// <summary>
    /// Gets or sets the type.
    /// </summary>
    /// <value>
    /// The type.
    /// </value>
    public FeedType Type
    {
      get { return _type; }
      set
      {
        _type = value;
        RaisePropertyChanged("Type");
        RaisePropertyChanged("Url");
      }
    }

    string _topic;

    /// <summary>
    /// Gets or sets the topic.
    /// </summary>
    /// <value>
    /// The topic.
    /// </value>
    public string Topic
    {
      get { return _topic; }
      set
      {
        _topic = value;
        RaisePropertyChanged("Topic");
        RaisePropertyChanged("Url");
      }
    }

    bool _enabled;

    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="FeedInfo"/> is enabled.
    /// </summary>
    /// <value>
    ///   <c>true</c> if enabled; otherwise, <c>false</c>.
    /// </value>
    public bool Enabled
    {
      get { return _enabled; }
      set
      {
        _enabled = value;
        RaisePropertyChanged("Enabled");
      }
    }


    /// <summary>
    /// Determines whether this instance is invalid.
    /// </summary>
    /// <returns>
    ///   <c>true</c> if this instance is invalid; otherwise, <c>false</c>.
    /// </returns>
    internal bool IsInvalid()
    {
      return Type == FeedType.None || 
        string.IsNullOrEmpty(_topic) || 
        string.IsNullOrEmpty(_title);
    }
  }
}
